package com.wcfsy.wechat.wx.util;

import java.io.InputStream;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class WechatPayment {

	private static Logger logger = LoggerFactory.getLogger(WechatPayment.class);
	/**
     * 获取支付所需签名
     * @param ticket
     * @param timeStamp
     * @param card_id
     * @param code
     * @return
     * @throws Exception
     */
    public static String getPayCustomSign(Map<String, String> bizObj,String key) throws Exception {
        String bizString = FormatBizQueryParaMap(bizObj,
                false);
        logger.info(bizString);
        return sign(bizString, key);
    }
    
    public static String FormatBizQueryParaMap(Map<String, String> paraMap,
            boolean urlencode) throws Exception {
        String buff = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(
                    paraMap.entrySet());
            Collections.sort(infoIds,
                    new Comparator<Map.Entry<String, String>>() {
                        public int compare(Map.Entry<String, String> o1,
                                Map.Entry<String, String> o2) {
                            return (o1.getKey()).toString().compareTo(
                                    o2.getKey());
                        }
                    });
            for (int i = 0; i < infoIds.size(); i++) {
                Map.Entry<String, String> item = infoIds.get(i);
                //System.out.println(item.getKey());
                if (item.getKey() != "") {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (urlencode) {
                        val = URLEncoder.encode(val, "utf-8");
                    }
                    buff += key + "=" + val + "&";
                }
            }
            if (buff.isEmpty() == false) {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
        return buff;
    }
    
    public static String sign(String content, String key)
            throws Exception{
        String signStr = "";
        signStr = content + "&key=" + key;
        return MD5(signStr).toUpperCase();
    }
    
    public final static String MD5(String s) {
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};       
        try {
            byte[] btInput = s.getBytes();
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
       }
    }
    
    public static String ArrayToXml(Map<String, String> arr) {
        String xml = "<xml>";
        Iterator<Entry<String, String>> iter = arr.entrySet().iterator();
        while (iter.hasNext()) {
            Entry<String, String> entry = iter.next();
            String key = entry.getKey();
            String val = entry.getValue();
            if (IsNumeric(val)) {
                xml += "<" + key + ">" + val + "</" + key + ">";
            } else
                xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">";
        }
        xml += "</xml>";
        return xml;
    }
    
    public static boolean IsNumeric(String str) {
        if (str.matches("\\d *")) {
            return true;
        } else {
            return false;
        }
    }
    
    public static String URL="https://api.mch.weixin.qq.com/pay/unifiedorder";
   
    @SuppressWarnings("deprecation")
    public static  JSONObject getPrepayJson(String xml){
    	InputStream reustl;
		try {
			reustl = HttpUtil.getInstance().phpPostInputStream(URL, xml);
			// XML转字符串    
			JSONObject o =xml2JSON(reustl);
//          return o;
			logger.info("payid 返回结果集 =====: "+ o.toJSONString());
			return o;
		} catch (Exception e) {
			logger.error("获取payid 失败" ,e);
		}
		return null;
//        HttpClient httpClient = new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true) ); 
//        InputStream is = null;
//         PostMethod method=null;
//        try {
//            String url =URL;
//             method = new PostMethod(url);
//             method.setRequestBody(xml);
//            httpClient.executeMethod(method);
//            //读取响应
//             is = method.getResponseBodyAsStream();
//            JSONObject o =xml2JSON(is);
//            return o;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }finally{
//            if(method!=null){
//                method.releaseConnection();
//            }
//            if(is!=null){
//                try {
//                    is.close();
//                } catch (IOException e1) {
//                    e1.printStackTrace();
//                }
//            }
//        }
//        return null;
    }
    public static String getPrepayid(String xml){
        try {
            JSONObject jo=getPrepayJson(xml);
            JSONObject element=jo.getJSONObject("xml");
            String prepayid=((JSONArray)element.get("prepay_id")).get(0).toString();
            return prepayid;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
	public static String orderNum(){
	        String chars = "0123456789";
	        String order = System.currentTimeMillis()+"";
	        String res = "";
	        for (int i = 0; i < 19; i++) {
	            Random rd = new Random();
	            res += chars.charAt(rd.nextInt(chars.length() - 1));
	        }
	        order+=res;
	        return order;
	 }
    
    /** 
     * 转换一个xml格式的字符串到json格式 
     *  
     * @param xml 
     *            xml格式的字符串 
     * @return 成功返回json 格式的字符串;失败反回null 
     */  
    @SuppressWarnings("unchecked")  
    public static  JSONObject xml2JSON(InputStream is) {  
        JSONObject obj = new JSONObject();  
        try {  
            SAXReader sb = new SAXReader();  
            Document doc = sb.read(is);
            Element root = doc.getRootElement();  
            obj.put(root.getName(), iterateElement(root));  
            return obj;  
        } catch (Exception e) {  
            logger.error("传入XML后转换JSON出现错误===== Xml2JsonUtil-->xml2JSON============>>",e);  
            return null;  
        }  
    }  
/** 
     * 一个迭代方法 
     *  
     * @param element 
     *            : org.jdom.Element 
     * @return java.util.Map 实例 
     */  
    @SuppressWarnings("unchecked")  
    private static Map  iterateElement(Element element) {  
        List jiedian = element.elements() ;
        Element et = null;  
        Map obj = new HashMap();  
        List list = null;  
        for (int i = 0; i < jiedian.size(); i++) {  
            list = new LinkedList();  
            et = (Element) jiedian.get(i);  
            if (et.getTextTrim().equals("")) {  
                if (et.elements().size() == 0)  
                    continue;  
                if (obj.containsKey(et.getName())) {  
                    list = (List) obj.get(et.getName());  
                }  
                list.add(iterateElement(et));  
                obj.put(et.getName(), list);  
            } else {  
                if (obj.containsKey(et.getName())) {  
                    list = (List) obj.get(et.getName());  
                }  
                list.add(et.getTextTrim());  
                obj.put(et.getName(), list);  
            }  
        }  
        return obj;  
    }  
}
